package source;

import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

import java.util.Timer;
import java.util.Vector;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;


public class Servidor {

	
	// *************** <Atributos> ***************
	
	private String direccionIp; // Direccion IP del servidor
	private ServerSocket direccionSocketServer; // Direccion SocketServer del servidor

	private int puerto; // Puerto del servidor

	private Vector clientes = new Vector(5, 2); // Vector que contiene la lista de sockets conectados

	
	// *************** <Constructor> ***************
	
	public Servidor(int port) {
		

		// Creamos un servidor en el puerto "port"
		try
		{
			direccionSocketServer = new ServerSocket(port);
		}
		catch (Exception e)
		{
			System.out.println("Excepcion: No se pudo crear el servidor :: " + e);
		}

		// Indicamos la direccion IP local 
		try
		{ 
			direccionIp = InetAddress.getLocalHost().getHostAddress();
		}
		catch (Exception e)
		{ 
			System.out.println("Excepcion: No se pudo obtener la direccion IP local"); 
		}
		

		// Asignamos el puerto en el que esta el servidor, al atributo puerto
		puerto = port;
		
		// Creamos la lista de cliente vacia
		clientes = new Vector();
	}

	// *************** <Consultas> ***************
	
	/**
	 * @return Devuelve la direccion ip del servidor
	 */
	public String getDireccionIp() {
		return direccionIp;
	}
	
	
	/**
	 * 
	 * @return Devuelve el puerto del Servidor
	 */
	public int getPuerto(){
		return puerto;
	}
	

	// *************** <Comandos> ***************

	public void enviarMensaje(Mensaje m) {

		ObjectOutputStream datosSalida;

		try
		{
			// Recorremos toda la lista de clientes y enviamos el mensaje a cada uno
			for (int i=0; i < clientes.size(); i++)
			{
				// Creamos un Flujo entre el servidor y el cliente
				datosSalida = new ObjectOutputStream(((Socket) clientes.elementAt(i)).getOutputStream());
				// Escribimos sobre el Flujo el objecto m de tipo Mensaje
				datosSalida.writeObject(m);
			}
		}
		catch (Exception e)
		{
			System.out.println("Excepcion: No se puedo enviar datos o crear el Flujo :: " + e);
		}
	}

	public Mensaje recibirMensaje() {
		
		ObjectInputStream datosEntrada;

		try
		{
			for (int i=0; i < clientes.size(); i++)
			{
				if (((Socket) clientes.elementAt(i)).getInputStream().available() != 0)
				{
					datosEntrada = new ObjectInputStream(((Socket) clientes.elementAt(i)).getInputStream());
					return((Mensaje) datosEntrada.readObject());
				}
			}

			return null; // Si no hay mensajes, devuelvo nulo
		}
		catch (Exception e)
		{
			System.out.println("Excepcion: No se puedo recibir datos :: " + e);
			return null;
		}
	}

	public void mostrarClientes() {

		for(int i=0; i < clientes.size(); i++)
		{
			System.out.print(clientes.elementAt(i)+"\n");
		}
	
	}


	public void aceptarClientes() {
		// Lanza el aceptador de clientes cada 1 segundo, pero solo si AceptadorDeClientes() finaliza se vuelve a lanzar
		Timer timer = new Timer();
		timer.schedule(new AceptadorDeClientes(clientes,direccionSocketServer),0, 1*1000);
	}


}

